package org.example.trigger.http;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.example.domain.activity.model.entity.ActivityAccountEntity;
import org.example.domain.activity.model.entity.PartakeRaffleActivityEntity;
import org.example.domain.activity.model.entity.UserRaffleOrderEntity;
import org.example.domain.activity.service.IActivityAccountQuota;
import org.example.domain.activity.service.IActivityPartakeService;
import org.example.domain.activity.service.armory.IActivityArmory;
import org.example.domain.award.model.entity.UserAwardRecordEntity;
import org.example.domain.award.model.valobj.AwardStateVO;
import org.example.domain.award.service.IAwardService;
import org.example.domain.rebate.model.entity.BehaviorEntity;
import org.example.domain.rebate.model.entity.BehaviorRebateOrderEntity;
import org.example.domain.rebate.model.valobj.BehaviorTypeVO;
import org.example.domain.rebate.service.IBehaviorRebateService;
import org.example.domain.strategy.model.Raffle.RaffleAwardEntity;
import org.example.domain.strategy.model.Raffle.RaffleFactorEntity;
import org.example.domain.strategy.service.IRaffleStrategy;
import org.example.domain.strategy.service.armory.IStrategyArmory;
import org.example.trigger.api.IRaffleActivityService;
import org.example.trigger.api.dto.ActivityDrawRequestDTO;
import org.example.trigger.api.dto.ActivityDrawResponseDTO;
import org.example.trigger.api.dto.UserActivityAccountRequestDTO;
import org.example.trigger.api.dto.UserActivityAccountResponseDTO;
import org.example.types.annotations.DCCValue;
import org.example.types.enums.ResponseCode;
import org.example.types.exception.AppException;
import org.example.types.model.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


@Slf4j
@CrossOrigin("${app.config.cross-origin}")
@RestController()
@RequestMapping("/api/${app.config.api-version}/raffle/activity/")
@DubboService(version = "1.0")
public class RaffleActivityController implements IRaffleActivityService {

    @Autowired
    private IStrategyArmory strategyArmory;

    @Autowired
    private IActivityArmory activityArmory;

    @Autowired
    private IAwardService awardService;

    @Autowired
    private IRaffleStrategy raffleStrategy;

    @Autowired
    private IActivityPartakeService raffleActivityPartakeService;

    @Autowired
    private IBehaviorRebateService behaviorRebateService;

    @Autowired
    private IActivityAccountQuota raffleActivityAccountQuota;

    @DCCValue("degradeSwitch:open")
    private String degradeSwitch;

    /**
     * 活动装配 - 数据预热 | 把活动配置的对应的 sku 一起装配
     *
     * @param activityId 活动ID
     * @return 装配结果
     * <p>
     * 接口：<a href="http://localhost:8091/api/v1/raffle/activity/armory">/api/v1/raffle/activity/armory</a>
     * 入参：{"activityId":100001,"userId":"xiaofuge"}
     *
     * curl --request GET \
     *   --url 'http://localhost:8091/api/v1/raffle/activity/armory?activityId=100301'
     */
    @RequestMapping(value = "armory" ,method = RequestMethod.GET)
    @Override
    public Response<Boolean> armory(Long activityId) {
        try {
            strategyArmory.assembleLotteryStrategyByActivityId(activityId);
            activityArmory.assembleActivitySkuByActivityId(activityId);
            return Response.<Boolean>builder()
                    .info(ResponseCode.SUCCESS.getInfo())
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(true)
                    .build();
        }  catch (AppException e) {
            log.info("预热失败  ");
            return Response.<Boolean>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception e) {
            log.info("预热失败  ");
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }


    }


    /**
     * 抽奖接口
     *
     * @param request 请求对象
     * @return 抽奖结果
     * <p>
     * 接口：<a href="http://localhost:8091/api/v1/raffle/activity/draw">/api/v1/raffle/activity/draw</a>
     * 入参：{"activityId":100001,"userId":"xiaofuge"}
     *
     * curl --request POST \
     *   --url http://localhost:8091/api/v1/raffle/activity/draw \
     *   --header 'content-type: application/json' \
     *   --data '{
     *     "userId":"xiaofuge",
     *     "activityId": 100301
     * }'
     */
    @RequestMapping(value = "draw" ,method =RequestMethod.POST)
    @Override
    public Response<ActivityDrawResponseDTO> draw(@RequestBody ActivityDrawRequestDTO request) {

        try {
            if (!"open".equals(degradeSwitch)) {
                return Response.<ActivityDrawResponseDTO>builder()
                        .code(ResponseCode.DEGRADE_SWITCH.getCode())
                        .info(ResponseCode.DEGRADE_SWITCH.getInfo())
                        .build();
            }

            Long activityId = request.getActivityId();
            String userId = request.getUserId();

            if (activityId ==null || StringUtils.isBlank(userId)){
                throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
            }

            //1.创建活动参与订单
            UserRaffleOrderEntity userRaffleOrderEntity = raffleActivityPartakeService.createOrder(PartakeRaffleActivityEntity.builder()
                    .activityId(activityId)
                    .userId(userId)
                    .build());
            //2.进行抽奖
            RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(RaffleFactorEntity.builder()
                    .userId(userId)
                    .strategyId(userRaffleOrderEntity.getStrategyId())
                    .endDateTime(userRaffleOrderEntity.getEndDateTime())
                    .build());

            //3.写入抽奖记录
            awardService.saveUserAwardRecord(UserAwardRecordEntity.builder()
                            .activityId(activityId)
                            .awardId(raffleAwardEntity.getAwardId())
                            .awardState(AwardStateVO.create)
                            .awardTitle(raffleAwardEntity.getAwardTitle())
                            .awardTime(new Date())
                            .orderId(userRaffleOrderEntity.getOrderId())
                            .userId(userId)
                            .config(raffleAwardEntity.getAwardConfig())
                            .strategyId(userRaffleOrderEntity.getStrategyId())
                    .build());

            return Response.<ActivityDrawResponseDTO>builder()
                    .info(ResponseCode.SUCCESS.getInfo())
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(ActivityDrawResponseDTO.builder()
                            .awardDesc(raffleAwardEntity.getAwardTitle())
                            .awardIndex(raffleAwardEntity.getSort())
                            .awardId(raffleAwardEntity.getAwardId())
                            .build())
                    .build();
        } catch (AppException e) {
            log.error("活动抽奖失败 userId:{} activityId:{}", request.getUserId(), request.getActivityId(), e);
            return Response.<ActivityDrawResponseDTO>builder()
                    .info(e.getInfo())
                    .code(e.getCode())
                    .build();
        }catch (Exception e) {
            log.error("活动抽奖失败 userId:{} activityId:{}", request.getUserId(), request.getActivityId(), e);
            return Response.<ActivityDrawResponseDTO>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }



    private final SimpleDateFormat dateFormatDay = new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     *  用户返利接口
     *  outBusinessNo 外部业务id
     * @param userId 用户id
     * @param behaviorTypeCode 行为类型
     * @param outBusinessNo 外部业务id,签到则为当天日期,支付则为外部的业务ID
     * @return
     */
    @RequestMapping(value = "calendar_rebate", method = RequestMethod.POST)
    @Override
    public Response<Boolean> calendarRebate(String userId,String behaviorTypeCode,String outBusinessNo) {
        try {
            BehaviorEntity behaviorEntity = BehaviorEntity.builder()
                    .userId(userId)
                    .behaviorTypeVO(BehaviorTypeVO.valueOf(behaviorTypeCode))
                    .outBusinessNo(outBusinessNo)
                    .build();
            List<String> orderIds = behaviorRebateService.createOrder(behaviorEntity);
            log.info("日历签到返利完成 userId:{} orderIds: {}", userId, JSON.toJSONString(orderIds));
            return Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(true)
                    .build();

        }catch (AppException e) {
            log.error("日历签到返利异常 userId:{} ", userId, e);
            return Response.<Boolean>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception e) {
            log.error("日历签到返利失败 userId:{}", userId);
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }

    }

    /**
     * 查询是否签到
     * 返利订单列表不为空则表示签到成功
     * @param userId 用户id
     * @param outBusinessNo 外部业务id:签到为当天日期字符串
     * @return
     */
    @RequestMapping(value = "is_calendar_sign_rebate", method = RequestMethod.POST)
    @Override
    public Response<Boolean> isCalendarSignRebate(String userId, String outBusinessNo) {
        try {
            List<BehaviorRebateOrderEntity> behaviorRebateOrderEntities = behaviorRebateService.queryRebateOrderByOutBusinessNo(userId,outBusinessNo);
            return Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(!behaviorRebateOrderEntities.isEmpty())
                    .build();
        } catch (AppException e) {
            log.error("查询用户是否完成日历签到返利失败 userId:{}", userId, e);
            return Response.<Boolean>builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();
        } catch (Exception exception) {
            log.error("查询用户是否完成日历签到返利失败 userId:{}", userId);
            return Response.<Boolean>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }

    }


    /**
     * 查询用户额度次数 总次数,总剩余,月次数,月剩余
     * @param requestDTO 用户id,活动id
     * @return
     */
    @RequestMapping(value = "query_user_activity_account", method = RequestMethod.POST)
    @Override
    public Response<UserActivityAccountResponseDTO> queryUserActivityAccount(UserActivityAccountRequestDTO requestDTO) {
        Long activityId = requestDTO.getActivityId();
        String userId = requestDTO.getUserId();

        ActivityAccountEntity activityAccountEntity = raffleActivityAccountQuota.queryUserActivityAccount(activityId,userId);

        if (activityAccountEntity == null)
            return Response.<UserActivityAccountResponseDTO>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(UserActivityAccountResponseDTO.builder()
                            .totalCount(0)
                            .totalCountSurplus(0)
                            .dayCount(0)
                            .dayCountSurplus(0)
                            .monthCount(0)
                            .monthCountSurplus(0)
                            .build())
                    .build();



        return Response.<UserActivityAccountResponseDTO>builder()
                .code(ResponseCode.SUCCESS.getCode())
                .info(ResponseCode.SUCCESS.getInfo())
                .data(UserActivityAccountResponseDTO.builder()
                        .totalCount(activityAccountEntity.getTotalCount())
                        .totalCountSurplus(activityAccountEntity.getTotalCountSurplus())
                        .dayCount(activityAccountEntity.getDayCount())
                        .dayCountSurplus(activityAccountEntity.getDayCountSurplus())
                        .monthCount(activityAccountEntity.getMonthCount())
                        .monthCountSurplus(activityAccountEntity.getMonthCountSurplus())
                        .build())
                .build();


    }


}
